﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace CoreRp.Services.Migrations
{
    internal static class MigrationManager
    {
        private static readonly object locker = new object();
        private static bool Migrated = false;
        public static string ConfigCode { get; } = "GOD_DB_VERSION";
        public static string ConfigType { get; } = "GOD_CODE";
        public static void ApplyMigration(IFreeSql Db)
        {
            if (!Migrated)
            {
                lock (locker)
                {
                    if (Migrated)
                    {
                        return;
                    }
                    else
                    {
                        #region 同步角色

                        var roles=E_Roles.GetValues(typeof(E_Roles));
                        foreach(var r in roles)
                        {

                            Type type = r.GetType();
                            FieldInfo fieldInfo = type.GetField(r.ToString());
                            // 判断是否加了特性注解
                            if (fieldInfo.IsDefined(typeof(RoleNameAttribute), true))
                            {
                                RoleNameAttribute attr = (RoleNameAttribute)fieldInfo.GetCustomAttribute(typeof(RoleNameAttribute), true);
                                var rolename = attr.name;
                                var remark = attr.remark;
                                var rolecode = r;
                                Db.InsertOrUpdate<Db_Models.RAP_ROLE>().SetSource(new Db_Models.RAP_ROLE()
                                {
                                    CREATETIME = DateTime.Now,
                                    ENABLE = "Y",
                                    ROLECODE = r.ToString(),
                                    ROLEDESC = remark,
                                    ROLENAME = rolename
                                }).ExecuteAffrows();
                                Console.WriteLine(rolename + ":" + r.ToString()+":"+r);

                            }
                        }


                        #endregion

                        var t =typeof(IMigration);
                        var vers=t.Assembly.GetTypes().Where(x => !x.IsInterface && x.GetInterfaces().Contains(t));

                        var ver_instaces = new List<IMigration>();

                        foreach(var v in vers)
                        {
                            if(v.Name== "IMigration")
                            {
                                continue;
                            }
                            Console.WriteLine("版本迁移文件：" + v.Name);
                            ver_instaces.Add((IMigration)t.Assembly.CreateInstance(v.FullName));
                        }
                        ver_instaces = ver_instaces.OrderBy(x => x.VersionTime).ToList();

                        Db.CodeFirst.SyncStructure<Db_Models.RAP_CONFIG>();

                        // 取最大的ODate
                        var cs=Db.Select<Db_Models.RAP_CONFIG>().Where(x => x.CODE == ConfigCode && x.BELONG== ConfigType).OrderByDescending<string>(x=>x.VALUE).First();

                        double oldVersion = 0;

                        // 如果没有任何已保存的ODate，则使用0
                        if (cs != null)
                        {
                            oldVersion=double.Parse(cs.VALUE);
                        }
                        Console.WriteLine("数据库中保存的旧版本的时间:" + oldVersion);
                        
                        Db.Transaction(() =>
                        {
                            foreach (var v in ver_instaces)
                            {
                                if (v.VersionTime.ToOADate() <= oldVersion)
                                {
                                    Console.WriteLine("数据版本" + v.VersionTime.ToString("yyyy年MM月dd日 HH:mm:ss") + "[" + v.VersionTime.ToOADate() + "]非最新版本，跳过迁移");
                                    continue;
                                }

                                try
                                {
                                    Console.WriteLine("数据版本" + v.VersionTime.ToString("yyyy年MM月dd日 HH:mm:ss") + "[" + v.VersionTime.ToOADate() + "]正在迁移");
                                    v.Run(Db);
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine(ex.Message);
                                    v.RollBack(Db);
                                }
                            }


                        });

                    }
                }
            }
        }
    }
}
